<?php
// 接口-调拨单接口
namespace interface\pda;

use verify;
use control\machiningOrderClass;
use control\inventoryBalanceClass;

class inventoryAllotClass extends index
{
	private const page        = 'inventoryAllot';
	private const table       = 'inventory_allot';
	private const tableMx     = 'inventory_allot_detail';
	private const tableRecord = 'inventory_record';
	private const title       = '调拨单';
	private const state       = ['草稿', '待确认', '已确认'];
	
	public function search()
	{
		$this->code         = 1;
		$this->resp['data'] = [
			'orderNo'     => '单据条码',
			'warehouseId' => find(['table' => 'warehouse', 'field' => 'id as value, name as text', 'where' => " coid = '" . self::$coid . "' AND state = '启用' "])['array'],
			'state'       => self::state,
		];
	}
	
	/**
	 * 列表
	 *
	 * @return void
	 */
	public function list()
	{
		//获取查询结果
		$where = " coid = '" . self::$coid . "' ";
		$equal = [
			'orderNo'        => $this->post('orderNo'),
			'outWarehouseId' => $this->post('outWarehouseId'),
			'inWarehouseId'  => $this->post('inWarehouseId'),
		];
		$like  = [
			'type'  => $this->post('type'),
			'state' => $this->post('state'),
		];
		$where .= search([
			"="    => $equal,
			"like" => $like,
		]);
		$page  = $this->page(["table" => self::table, "where" => $where, "order" => "time desc"]);
		//数据分析
		$data['result'] = [];
		foreach ($page['array'] as $array) {
			$num              = find(['table' => self::tableMx, 'where' => "orderId = '$array[id]'", 'sum' => "num"]);
			$money            = find(['table' => self::tableMx, 'where' => "orderId = '$array[id]'", 'sum' => "price"]);
			$result           = find([
				'table'  => self::tableMx,
				'field'  => ' any_value(materialId) as materialId, IFNULL(sum(num), 0) as total ',
				'single' => " orderId = '$array[id]' ",
			]);
			$material         = query('material', " id = '$result[materialId]' ");
			$data['result'][] = [
				'id'           => $array['id'],
				'orderNo'      => $array['orderNo'],
				'outWarehouse' => $array['outWarehouse'],
				'inWarehouse'  => $array['inWarehouse'],
				'material'     => $material['name'] . '等' . static::formattingFigure($result['total']) . $material['unit'],
				'type'         => $array['type'],
				'num'          => $num,
				'money'        => $money,
				'orderDate'    => $array['orderDate'],
				'state'        => $array['state'],
			];
		}
		$data['page'] = $page['para'];
		//返回
		$this->code         = 1;
		$this->resp['data'] = $data;
	}
	
	
	/**
	 * 编辑
	 */
	public function edit(): void
	{
		$detail           = !empty($_POST['detail']) ? json_decode($_POST['detail'], true) : [];
		$id               = $this->post('id') ?: self::getId();
		$mxIdArr          = $this->post('mxId') ?: inStockClass::getJsonValue('id', $detail);
		$materialSkuIdArr = $this->post('materialSkuId') ?: inStockClass::getJsonValue('materialSkuId', $detail);
		$inventoryNumArr  = $this->post('inventoryNum') ?: inStockClass::getJsonValue('inventoryNum', $detail);
		$unitArr          = $this->post('unit') ?: inStockClass::getJsonValue('unit', $detail);
		$numArr           = $this->post('num') ?: inStockClass::getJsonValue('num', $detail);
		$batchArr         = $this->post('batch') ?: inStockClass::getJsonValue('batch', $detail);
		$mxTextArr        = $this->post('mxText') ?: inStockClass::getJsonValue('mxText', $detail);
		$field            = [
			'outWarehouse'   => $this->post('outWarehouse'),
			'outWarehouseId' => $this->post('outWarehouseId'),
			'inWarehouseId'  => $this->post('inWarehouseId'),
			'inWarehouse'    => $this->post('inWarehouse'),
			'orderDate'      => $this->post('orderDate'),
			'type'           => $this->post('type'),
			'text'           => $this->post('text'),
		];
		$annotation       = [
			'outWarehouse'   => '调出仓库',
			'outWarehouseId' => '调入仓库',
			'inWarehouseId'  => '调入仓库',
			'inWarehouse'    => '调入仓库',
			'orderDate'      => '单据日期',
			'type'           => '类型',
			'text'           => '备注',
		];
		$rules            = [
			'outWarehouse'   => 'required',
			'outWarehouseId' => 'required',
			'inWarehouseId'  => 'required',
			'inWarehouse'    => 'required',
			'orderDate'      => 'required',
			// 'type'           => 'required',
			// 'text'           => 'required',
		];
		// 校验是否符合规则
		$vt     = new verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$this->resp['warn'] = $vt->getErrs()[0]; // 多个规则提示最前面一条
			goto resp;
		}
		$where = " id = '$id' ";
		$info  = query(self::table, $where);
		//判断
		if (!$this->power(self::page, "edit")) {
			$this->resp['warn'] = "你没有编辑" . self::title . "的权限";
		} elseif ($field['outWarehouseId'] == $field['inWarehouseId']) {
			$this->resp['warn'] = '调出仓库和调入仓库不能相同';
		} elseif (self::is_null_array($mxIdArr)) {
			$this->resp['warn'] = '请选择调拨明细';
		} elseif (self::is_null_array($materialSkuIdArr)) {
			$this->resp['warn'] = '请选择调拨明细';
		} elseif (self::is_null_array($numArr)) {
			$this->resp['warn'] = '数量请填写完整';
		} elseif (self::is_null_array($unitArr)) {
			$this->resp['warn'] = '请选择主单位';
		} elseif (!empty($info['id']) && $info['state'] == '已确认') {
			$this->resp['warn'] = '此调拨单已确认，不能修改';
		} else {
			$this->startTrans();
			$isPass = true;//事务通过标志
			if (!$info['id']) {
				$orderNo            = self::generateCode(self::page, [
					'prefix' => 'DB' . date('Ymd'),
					'table'  => self::table,
					'field'  => 'orderNo',
					'where'  => " AND coid = '" . self::$coid . "' ",
				], $field);
				$field              = array_merge($field, [
					'id'      => $id,
					'orderNo' => $orderNo,
					'state'   => '待确认',
					'coid'    => self::$coid,
					'stid'    => $this->control['stid'],
				]);
				$this->resp['warn'] = static::insert([
					"table" => self::table,
					"field" => $field,
				]);
			} else {
				$this->resp['warn'] = static::update([
					"table" => self::table,
					"field" => $field,
					"where" => $where,
				]);
			}
			//添加或更新报价单明细
			if (is_array($mxIdArr)) {
				foreach ($mxIdArr as $k => $nid) {
					$mx          = query(self::tableMx, "id = '$nid'");
					$materialSku = query('material_sku', "id = '$materialSkuIdArr[$k]'");
					$material    = query('material', "id = '$materialSku[materialId]'");
					if ($inventoryNumArr[$k] < $numArr[$k]) {
						$this->resp['warn'] = '【' . $material['code'] . ' - ' . $material['name'] . ' - ' . $material['model'] . ' - ' . $materialSku['name'] . '】' . '调拨数量不能大于库存数量';
						goto resp;
					}
					if (!empty($mx['id'])) {
						//更新
						$warn = static::update([
							"table" => self::tableMx,
							"field" => [
								'coid'          => self::$coid,
								'materialId'    => $materialSku['materialId'],
								'materialSkuId' => $materialSkuIdArr[$k],
								'orderNum'      => $numArr[$k],
								'inventoryNum'  => $numArr[$k],
								'batch'         => $batchArr[$k],
								'num'           => 0,
								'price'         => inventoryBalanceClass::unitPrice($materialSku['id']),
								'unit'          => $unitArr[$k],
								'text'          => $mxTextArr[$k],
							],
							"where" => " id = '$nid'",
						]);
					} else {
						//新增
						$warn = static::insert([
							"table" => self::tableMx,
							"field" => [
								'id'            => $nid,
								'coid'          => self::$coid,
								'orderId'       => $id,
								'materialId'    => $materialSku['materialId'],
								'materialSkuId' => $materialSkuIdArr[$k],
								'orderNum'      => $numArr[$k],
								'inventoryNum'  => $numArr[$k],
								'num'           => 0,
								'batch'         => $batchArr[$k],
								'price'         => inventoryBalanceClass::unitPrice($materialSku['id']),
								'unit'          => $unitArr[$k],
								'text'          => $mxTextArr[$k],
							],
						]);
					}
					if (!in_array($warn, ['新增成功', '更新成功'])) {
						$isPass             = false;
						$this->resp['warn'] = $warn;
						break;
					}
				}
			}
			if (in_array($this->resp['warn'], ["新增成功", "更新成功"]) && $isPass) {
				$this->commitTrans();
				delete(['table' => self::tableMx, 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"]);
				//添加日志
				$type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				$this->resp['data'] = $id;
				//返回
				$this->code = 1;
			} else {
				$this->rollback();
			}
		}
		
		resp:
	}
	
	/**
	 * 确认
	 */
	public function done()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
		$field = [
			'state'       => '已确认',
			'checkId'     => self::$stid,
			'confirmTime' => $this->time,
		];
		if (!$this->power(self::page, 'confirm')) {
			$this->resp['warn'] = '你还没有确认权限';
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = '未找到此调拨单';
		} elseif ($info['state'] != '待确认') {
			$this->resp['warn'] = '此调拨单非待确认状态，不能确认';
		} else {
			$this->startTrans();
			$isPass             = true; // 事务通过标志
			$this->resp['warn'] = static::update([
				"table" => self::table,
				"field" => $field,
				"where" => "id = '$info[id]'",
			]);
			if (in_array($this->resp['warn'], ["新增成功", "更新成功"]) && $isPass === true) {
				$details = find([
					'table' => self::tableMx,
					'where' => " orderId = '{$info['id']}'",
				]);
				foreach ($details['array'] as $value) {
					// 转换主单位
					$mainUnitNum = inventoryBalanceClass::toMainUnit($value['materialSkuId'], $value['num'], $value['unit']);
					// 入
					static::insert([
						'table' => self::tableRecord,
						'field' => [
							'id'            => self::getNo(),
							'coid'          => self::$coid,
							'warehouseId'   => $info['inWarehouseId'],
							'materialId'    => $value['materialId'],
							'materialSkuId' => $value['materialSkuId'],
							'num'           => $mainUnitNum,
						],
					]);
					// 出
					static::insert([
						'table' => self::tableRecord,
						'field' => [
							'id'            => self::getNo(),
							'coid'          => self::$coid,
							'warehouseId'   => $info['outWarehouseId'],
							'materialId'    => $value['materialId'],
							'materialSkuId' => $value['materialSkuId'],
							'num'           => -1 * $mainUnitNum,
						],
					]);
				}
				// 补出入库记录
				inventoryBalanceClass::otherToinventory(self::table, $id);
				$this->commitTrans();//提交事务
				auditingFollow(array(
					"type"   => "调拨单",
					"typeId" => $info['id'],
					"text"   => "【{$this->control['name']}】确认",
				));
				//添加日志
				$type               = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
				$text               = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
				$this->resp['data'] = [
					'id'      => $info['id'],
					'orderNo' => $info['orderNo'],
				];
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$this->code = 1;
			}
		}
		resp:
	}
	
	/**
	 * 删除
	 *
	 * @return void
	 */
	public function delete(): void
	{
		$array = $this->post('listId') ?? $this->post('id');
		if (!$this->power(self::page, "del")) {
			$this->resp['warn'] = "你没有删除的权限";
		} elseif (empty($array)) {
			$this->resp['warn'] = "你一个数据都没有选择呢";
		} else {
			$text  = "";
			$x     = 0;
			$array = is_array($array) ? $array : [$array];
			foreach ($array as $id) {
				$info = query(self::table, " id = '$id' ");
				if ($info['state'] == '已出库') {
					$warn = "删除失败：已出库，暂不能删除";
				} else {
					//最后删除基本参数
					delete(array("table" => self::table, "where" => " id = '$id' "));
					delete(array("table" => self::tableMx, "where" => " orderId = '$id' "));
					delete(array("table" => 'auditing_follow', "where" => " typeId = '$id' "));
					//返回
					$warn = "删除成功";
					$x++;
				}
				$text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
			}
			//添加日志
			$text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
			$this->logText(array("type" => self::page, "text" => $text));
			$this->resp['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
			$this->code         = 1;
		}
	}
	
	/**
	 * 详情
	 *
	 * @return void
	 */
	public function detail()
	{
		$id   = $this->post('id');
		$info = query(self::table, "id = '" . $id . "'");
		if (empty($id)) {
			$this->resp['warn'] = "ID为空";
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = "未找到此" . self::title;
		} else {
			$audit  = find([
				'table' => 'auditing_follow',
				'where' => " typeId = '$info[id]'",
			]);
			$result = find([
				'table' => self::tableMx,
				'where' => " orderId = '$info[id]' ",
			]);
			$detail = $allotRecord = [];
			foreach ($result['array'] as $value) {
				$material    = query('material', " id = '$value[materialId]' ");
				$materialSku = query('material_sku', " id = '$value[materialSkuId]' ");
				$rid         = self::generateId([$value['orderId'], $value['materialSkuId']]);
				$temp        = find(['table' => 'auditing_follow', 'where' => "typeId = '$rid' AND type = '调拨单' order by time desc"])['array'];
				$position    = query('warehouse_position', "id = '$value[positionId]'");
				$detail[]    = [
					'id'              => $value['id'],
					'materialId'      => $value['materialId'],
					'materialSkuId'   => $value['materialSkuId'],
					'code'            => $material['code'],
					'name'            => $material['name'],
					'model'           => $material['model'],
					'positionId'      => $value['positionId'],
					'position'        => $position['name'],
					'unit'            => $material['unit'],
					'batch'           => $value['batch'],
					'num'             => $value['num'],
					'price'           => $value['price'],
					'mxText'          => $value['text'],
					'materialSkuName' => $materialSku['name'],
					'brand'           => $material['brand'],
					'mtype'           => inventoryListClass::getTypeName($material['typeId']),
					'text'            => $value['text'],
					'orderNum'        => $value['orderNum'],
					'inventoryNum'    => $value['inventoryNum'],
					// 可用库存计算
					'usableNum'       => machiningOrderClass::inventory($value['materialSkuId'], $value['unit'], $position['orderId']),
					'unitArray'       => inventoryBalanceClass::materialUnit($value['id']),
					'total'           => $value['num'] * $value['price'],
				];
				if (!self::is_null_array($temp)) {
					$allotRecord = array_merge($allotRecord, $temp);
				}
			}
			$data['result'] = [
				'info'        => [
					'id'           => $info['id'],
					"outWarehouse" => $info['outWarehouse'],
					"inWarehouse"  => $info['inWarehouse'],
					"orderDate"    => $info['orderDate'],
					"type"         => $info['type'],
					"text"         => $info['text'],
					"orderNo"      => $info['orderNo'],
					"stName"       => self::findStaff($info['stid']),
					"stid"         => $info['stid'],
					"state"        => $info['state'],
				],
				'detail'      => $detail,
				'auditRecord' => $audit['array'],
				'allotRecord' => $allotRecord ? self::my_sort($allotRecord, 'time', SORT_DESC, SORT_STRING) : [],
			];
			//返回
			$this->code         = 1;
			$this->resp['data'] = $data;
		}
	}
	
	/**
	 * 入库
	 */
	public function putIn()
	{
		$id   = $this->post('id');
		$num  = $this->post('num');
		$info = query(self::tableMx, " id = '$id'");
		$res  = query(self::table, " id = '$info[orderId]' ");
		if (!$this->power(self::page, 'edit')) {
			$this->resp['warn'] = '你还没有入库权限';
		} elseif (empty($res['id'])) {
			$this->resp['warn'] = '未找到此入库单';
		} elseif (static::isNull($num)) {
			$this->resp['warn'] = '请填写数量';
		} elseif (!in_array($res['state'], ['待确认'])) {
			$this->resp['warn'] = '此调拨单不是待确认状态，不能入库';
		} elseif (abs($num) + $info['num'] > $info['orderNum']) {
			$this->resp['warn'] = '入库数量不能超过单据数量，你还可以入库' . ($info['orderNum'] - $info['num']);
		} else {
			$num                = abs($num);
			$this->resp['warn'] = static::update([
				"table" => self::tableMx,
				"field" => [
					'num' => $info['num'] + $num,
				],
				"where" => "id = '$info[id]'",
			],);
			if (in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
				$material = query('material', " id = '$info[materialId]' ", 'code, name, brand, model');
				auditingFollow([
					"type"   => "调拨单",
					"typeId" => self::generateId([$info['orderId'], $info['materialSkuId']]),
					"text"   => "【{$this->control['name']}】通过【前端】调拨【{$material['name']}-{$material['brand']}-{$material['model']}】数量[$num]",
				]);
				$this->resp['data'] = $res['id'];
				$this->code         = 1;
			}
		}
		resp:
	}
}